package udp;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.LinkedList;

import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;

import com.audiobuddy.serializables.Song;

import threads.AcceptCommandsThread;
import threads.AcceptSongsThread;
import threads.MulticastServerIp;
import threads.SendPlaylistOnRequestThread;

import domain.ServerDomainController;

public class UDPController {

	
	private static final int MULTICAST_PORT = 4444;
	private static final int REQUEST_STREAM_PORT = 7777;
	private static final int STOP_BROADCAST_PORT = 8889;
	private ServerDomainController dc;
	private DatagramSocket requestStreamSocket;
	

	public UDPController(ServerDomainController serverDomainController) {
		this.dc = serverDomainController;
		multicastServerIp();
		sendPlaylistOnRequest();
		acceptSongs();
		acceptCommands();
	}

	private void multicastServerIp() {
		new MulticastServerIp().start();
		
	}

	private void acceptCommands() {
		new AcceptCommandsThread(dc).start();
		
	}

	private void acceptSongs() {
		new AcceptSongsThread(dc).start();
		
	}

	private void sendPlaylistOnRequest() {
		new SendPlaylistOnRequestThread(dc).start();
		
		
	}

	public void multicastPlaylist() {
		try {
			DatagramSocket dgSocket = new DatagramSocket();
			InetAddress group = InetAddress.getByName("230.0.0.1");
			
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(baos));
			oos.flush();
			oos.writeObject(dc.getSongs());
			oos.flush();
			
			DatagramPacket packet = new DatagramPacket(baos.toByteArray(), baos.size(), group, MULTICAST_PORT);
			dgSocket.send(packet);
			dgSocket.close();
		} catch (SocketException e) {
			System.out.println(e);
		} catch (UnknownHostException e) {
			System.out.println(e);
		} catch (IOException e) {
			System.out.println(e);
		}
		
	}

	public void requestStartStreamingSong(Song song) {
		InetAddress clientIp = song.getClientIP();
		String absolutePath = song.getAbsolutePath();
		try{
			requestStreamSocket = new DatagramSocket();
			requestStreamSocket.setReuseAddress(true);
			DatagramPacket outPacket = new DatagramPacket(absolutePath.getBytes(), absolutePath.length(),
					clientIp,REQUEST_STREAM_PORT);
			requestStreamSocket.send(outPacket);
			System.out.println("Send stream request to " + clientIp.toString());
			//return dc.tcpAcceptFile();
			
			/*byte[] songBuffer = new byte[8192];   //8MB NU, WERKT WRS NIET ALS MEER IS
			DatagramPacket inPacket = new DatagramPacket(songBuffer, songBuffer.length);
			requestStreamSocket.receive(inPacket);
			System.out.println("receiving file from client...");
			ByteArrayInputStream bais = new ByteArrayInputStream(songBuffer);
			ObjectInputStream ois = new ObjectInputStream(bais);
			return (File) ois.readObject();*/
			
		}catch (IOException e) {
			System.out.println("IOException on request stream song: "+ e);
		}finally{
			requestStreamSocket.close();
		}
		
	}

	public void stopBroadcasting(InetAddress broadcasterIp) {
		try{
			DatagramSocket s = new DatagramSocket();
			String stop = "stop";
			DatagramPacket p = new DatagramPacket(stop.getBytes(), stop.length(), broadcasterIp, STOP_BROADCAST_PORT);
			s.send(p);
			s.close();
		}catch (IOException e) {
			System.out.println("error sending stop broadcast message");
		}
		
	}

	public void multicastCurrentlyPlaying(Song currentSong) {
		try {
			DatagramSocket dgSocket = new DatagramSocket(4446);
			InetAddress group = InetAddress.getByName("230.0.0.1");
			
			String currently = "current::" + currentSong.getArtist() + " - " + currentSong.getTitle();
			
			DatagramPacket packet = new DatagramPacket(currently.getBytes(), currently.length(), group, MULTICAST_PORT);
			dgSocket.send(packet);
			dgSocket.close();
		} catch (SocketException e) {
			System.out.println(e);
		} catch (UnknownHostException e) {
			System.out.println(e);
		} catch (IOException e) {
			System.out.println(e);
		}
	}

}
